﻿using GZHJ.Tool;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using VM.Shared.TestAttribute;

namespace 卓品蓝牙盒
{
    [ExposedMethodAttribute("卓品蓝牙盒控制")]
    public class 蓝牙盒
    {
        SerialPort serialPort;
        string ReadDate = "";

        [ExposedMethodAttribute("复位蓝牙盒")]
        public bool 复位蓝牙盒(string 串口, out string 错误信息)
        {
            try
            {
                string sendData = "*RST";
                错误信息 = "";
                if (!OpenPort(串口, out 错误信息))
                {
                    return false;
                }
                ReadDate = "";
                Thread.Sleep(10);
                if (serialPort.IsOpen)
                {
                    serialPort.Write(sendData); // 写入数据
                    Console.WriteLine("发送数据" + sendData);
                    Thread.Sleep(100);

                    ReadDate = serialPort.ReadExisting();
                    if (ReadDate.Contains("ACK"))
                    {
                        ClosePort();//关闭串口 
                        return true;
                    }
                }
                else
                {
                    Console.WriteLine("串口打开失败");
                    错误信息 = "串口打开失败";
                }

                ClosePort();//关闭串口 
            }
            catch (Exception ex)
            {

                错误信息 = ex.Message;
            }
            ClosePort();//关闭串口 
            return false;
        }

        [ExposedMethodAttribute("")]
        public bool 连接蓝牙(string 串口, string Mac地址, out string 错误信息)
        {
            if (!OpenPort(串口, out 错误信息))
            {
                return false;
            }
            bool ok = 发送接收(串口, "AT+SCON=" + Mac地址 + "\n", "OK", out 错误信息);
            ClosePort();
            return ok;
        }

        [ExposedMethodAttribute("断开连接")]
        public bool 断开连接(string 串口, out string 错误信息)
        {
            if (!OpenPort(串口, out 错误信息))
            {
                return false;
            }
            bool ok = 发送接收(串口, "AT+SDSC" + "\n", "OK", out 错误信息);
            ClosePort();
            return ok;
        }
        [ExposedMethodAttribute("")]
        public bool 挂断电话(string 串口, out string 错误信息)
        {
            if (!OpenPort(串口, out 错误信息))
            {
                return false;
            }
            bool ok = 发送接收(串口, "AT+CINT" + "\n", "OK", out 错误信息);
            ClosePort();
            return ok;
        }
        [ExposedMethodAttribute("")]
        public bool 接听电话(string 串口, out string 错误信息)
        {
            if (!OpenPort(串口, out 错误信息))
            {
                return false;
            }
            bool ok = 发送接收(串口, "AT+CATV" + "\n", "OK", out 错误信息);
            ClosePort();
            return ok;
        }
        [ExposedMethodAttribute("")]
        public bool 来电(string 串口, out string 错误信息, string 号码 = "13560065511")
        {
            if (!OpenPort(串口, out 错误信息))
            {
                return false;
            }
            bool ok = 发送接收(串口, "AT+CVIM=" + 号码 + "\n", "OK", out 错误信息);
            ClosePort();
            return ok;
        }
        [ExposedMethodAttribute("")]
        public bool 去电(string 串口, out string 错误信息, string 号码 = "10086")
        {
            if (!OpenPort(串口, out 错误信息))
            {
                return false;
            }
            bool ok = 发送接收(串口, "AT+COUT=" + 号码 + "\n", "OK", out 错误信息);
            ClosePort();
            return ok;
        }
        [ExposedMethodAttribute("")]
        public bool 波形输出(string 串口, out string 错误信息, int 电压值20_2000 = 1000, int 频率Hz = 1000)
        {
            错误信息 = "";

            if (!信号源出力(串口, out 错误信息, 电压值20_2000))
            {
                return false;
            }
            Thread.Sleep(100);
            if (!信号源频率(串口, out 错误信息, 频率Hz))
            {
                return false;
            }
            Thread.Sleep(100);
            if (!信号源输出(串口, out 错误信息, true))
            {
                return false;
            }

            return true;
        }

        [ExposedMethodAttribute("")]
        public bool 信号源出力(string 串口, out string 错误信息, int 电压值20_20000 = 1000)
        {
            if (电压值20_20000 < 20)
            {
                电压值20_20000 = 20;
            }
            else if (电压值20_20000 > 20000)
            {
                电压值20_20000 = 20000;
            }
            bool ok = false;
            错误信息 = "";
            if (!OpenPort(串口, out 错误信息))
            {
                return false;
            }
            for (int i = 0; i < 3; i++)
            {
                错误信息 = "";
                ok = 发送接收(串口, "ACLP:" + 电压值20_20000.ToString() + "\n", "ACK", out 错误信息);
                if (ok)
                {
                    break;
                }

                Thread.Sleep(100);
            }
            ClosePort();
            return ok;
        }

        [ExposedMethodAttribute("")]
        public bool 信号源频率(string 串口, out string 错误信息, int 频率Hz = 1000)
        {
            /*
             * 功      能： 内部信号源频率设置
                  指令格式：ACFR:<val>  其中<val>为频率值，范围为20~30000，单位为Hz   
                  应答格式： 成功时应答"ACK"   
                  注意事项：
                  1.频率值设定值复位或断电后不保存，断电或复位初始值为1000 Hz
                    ACFR:%d
             */
            bool ok = false;
            if (!OpenPort(串口, out 错误信息))
            {
                return false;
            }
            for (int i = 0; i < 3; i++)
            {
                错误信息 = "";
                ok = 发送接收(串口, "ACFR:" + 频率Hz.ToString() + "\n", "ACK", out 错误信息);
                if (ok)
                {
                    break;
                }

                Thread.Sleep(100);
            }
            ClosePort();
            return ok;

        }
        [ExposedMethodAttribute("")]
        public bool 信号源输出(string 串口, out string 错误信息, bool 输出 = true)
        {
            /*
             * 功      能： 内部信号源输出状态设置
                指令格式：ACTP<st>  其中<st>为状态值，范围为0~3，其定义如下：
                   0 ： 输出关闭
                   1  :   输出正弦波（开机默认）
                   2  :   输出三角波 ( 仅供设备调试，请勿使用）
                   3  :   输出方波   ( 仅供设备调试，请勿使用
                      应答格式： 成功时应答“ACK”
                      注意事项：
                  1. 输出三角波和输出方波仅供卓品内部供设备调试时使用，如在产品测试中请勿使用，否则将会出现不可预测的结果！
                  2. 设定值复位或断电后不保存，断电或复位初始值为1 
                 ACTP:%d
             */
            int 模式 = 1;
            错误信息 = "";
            if (输出)
            {
                模式 = 1;
            }
            else
            {
                模式 = 0;
            }
            bool ok = false;
            if (!OpenPort(串口, out 错误信息))
            {
                return false;
            }
            for (int i = 0; i < 3; i++)
            {
                错误信息 = "";
                ok = 发送接收(串口, "ACMI:2" + "\n", "ACK", out 错误信息);
                if (ok)
                {
                    break;
                }

                Thread.Sleep(100);
            }
            if (!ok)
            {
                return false;
            }
            for (int i = 0; i < 3; i++)
            {
                错误信息 = "";
                ok = 发送接收(串口, "ACTP:" + 模式.ToString() + "\n", "ACK", out 错误信息);
                if (ok)
                {
                    break;
                }

                Thread.Sleep(100);
            }
            ClosePort();
            return ok;
        }
        [ExposedMethodAttribute("")]
        public bool 连接状态(string 串口, out string 信息)
        {
            /*
        *  <st>=0：初始化，
                 <st>=1：掉电状态，
                 <st>=2：测试模式，
                 <st>=3：空闲，
                 <st>=4：可被连接，
                 <st>=5：可被发现，
                 <st>=6：连接中，
                 <st>=7：搜索中，
                 <st>=8：已连接 ，  
        */
            //增加打开关闭串口操作，修复报异常的问题，2024-10-30
            if (!OpenPort(串口, out 信息))
            {
                return false;
            }
            var 发送结果 = 发送接收(串口, "AT+STATE=?", "8", out 信息);
            ClosePort();
            return 发送结果;
        }

        [ExposedMethodAttribute("")]
        public bool 当前连接信号强度(string 串口, out string 信息)
        {
            /*
        *  功      能：查询当前已连接的远程蓝牙信号强度
  指令格式：AT+RSSI=？
  应答格式：成功时应答远程蓝牙信号强度，格式如下：
                 OK
                 +RSSI:BEGIN
                 +RSSI=<n>     //<n>为远程蓝牙信号强度，单位为dbm  范围为:0~-127
                 +RSSI:END
  
        */
            //增加打开关闭串口操作，修复报异常的问题，2024-10-30
            if (!OpenPort(串口, out 信息))
            {
                return false;
            }
            var 发送结果 = 发送接收(串口, "AT+RSSI=?", "OK", out 信息);
            ClosePort();
            return 发送结果;
        }



        private bool 发送接收(string 串口, string sendData, string 比较, out string 信息)
        {
            try
            {
                信息 = "";
                ReadDate = "";
                Thread.Sleep(20);
                if (serialPort.IsOpen)
                {
                    serialPort.Write(sendData); // 写入数据
                    //Console.WriteLine("发送数据" + sendData);
                    Thread.Sleep(100);

                    ReadDate = serialPort.ReadExisting();
                    if (ReadDate.Contains(比较))
                    {
                        信息 = ReadDate;
                        return true;
                    }
                }
                else
                {
                    //Console.WriteLine("串口打开失败");
                    信息 = "串口打开失败";
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error($"[卓品蓝牙盒.蓝牙盒.发送接收]异常，{ex.Message},{ex.StackTrace}");
                信息 = ex.Message;
            }
            return false;
        }
        /// <summary>
        /// 打开串口
        /// </summary>
        /// <param name="串口"></param>
        /// <param name="信息"></param>
        /// <returns></returns>
        private bool OpenPort(string 串口, out string 信息)
        {
            信息 = "";

            for (int i = 0; i < 3; i++)
            {
                try
                {
                    信息 = "";
                    serialPort = new SerialPort(串口, 115200, Parity.None, 8, StopBits.One); // 设置串口参数
                    Thread.Sleep(10);
                    serialPort.Open(); // 打开串口
                    return true;
                }
                catch (Exception ex)
                {
                    LogHelper.Error($"[卓品蓝牙盒.蓝牙盒.OpenPort]异常，{ex.Message},{ex.StackTrace}");
                    信息 = ex.Message;
                }
            }

            return false;
        }
        /// <summary>
        /// 关闭串口
        /// </summary>
        private void ClosePort()
        {
            if (serialPort.IsOpen)
            {
                serialPort.Close(); // 关闭串口
            }
            serialPort = null;
        }
    }
}
